#include "connect.h"
#include "ui_connect.h"
#include <QtMath>

Connect::Connect(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Connect)
    ,tcpServer(new QTcpServer(this)),
    currentConnection(nullptr)
{
    ui->setupUi(this);
    setupUI();
    connect(tcpServer, &QTcpServer::newConnection, this, &Connect::newConnection);
}

Connect::~Connect()
{
    delete ui;
}

void Connect::setupUI()
{
    // 主布局
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setSpacing(10);
    mainLayout->setContentsMargins(10, 10, 10, 10);

    // 端口设置布局
    QHBoxLayout *portLayout = new QHBoxLayout();

    listenPortSpinBox = new QSpinBox(this);
    listenPortSpinBox->setRange(1024, 65535);
    listenPortSpinBox->setValue(8888);

    startButton = new QPushButton("开始监听", this);
    stopButton = new QPushButton("停止监听", this);
    stopButton->setEnabled(false);

    connect(startButton, &QPushButton::clicked, this, &Connect::startListening);
    connect(stopButton, &QPushButton::clicked, this, &Connect::stopListening);

    portLayout->addWidget(new QLabel("监听端口:", this));
    portLayout->addWidget(listenPortSpinBox);
    portLayout->addWidget(startButton);
    portLayout->addWidget(stopButton);

    // 状态标签
    statusLabel = new QLabel("状态: 未启动", this);
    statusLabel->setAlignment(Qt::AlignCenter);

    // 数据显示区
    textEdit = new QTextEdit(this);
    textEdit->setReadOnly(true);

    // 添加组件到主布局
    mainLayout->addLayout(portLayout);
    mainLayout->addWidget(statusLabel);
    mainLayout->addWidget(textEdit);

    setLayout(mainLayout);
    setWindowTitle("雷达点数据接收服务端");
    resize(600, 500);
}

void Connect::startListening()
{
    quint16 port = static_cast<quint16>(listenPortSpinBox->value());
    if (tcpServer->listen(QHostAddress::Any, port)) {
        statusLabel->setText(QString("正在监听端口 %1").arg(port));
        startButton->setEnabled(false);
        stopButton->setEnabled(true);
    } else {
        statusLabel->setText("监听失败: " + tcpServer->errorString());
    }
}

void Connect::stopListening()
{
    if (currentConnection) {
        currentConnection->disconnectFromHost();
        currentConnection = nullptr;
    }
    tcpServer->close();
    statusLabel->setText("已停止监听");
    startButton->setEnabled(true);
    stopButton->setEnabled(false);
}

void Connect::newConnection()
{
    if (currentConnection) {
        QTcpSocket *newSocket = tcpServer->nextPendingConnection();
        newSocket->close();
        newSocket->deleteLater();
        statusLabel->setText("已有连接，拒绝新连接");
        return;
    }

    currentConnection = tcpServer->nextPendingConnection();
    connect(currentConnection, &QTcpSocket::readyRead, this, &Connect::readData);
    connect(currentConnection, &QTcpSocket::disconnected, this, &Connect::disconnected);

    statusLabel->setText(QString("客户端连接: %1:%2")
                             .arg(currentConnection->peerAddress().toString())
                             .arg(currentConnection->peerPort()));
}

void Connect::disconnected()
{
    if (sender() == currentConnection) {
        currentConnection->deleteLater();
        currentConnection = nullptr;
        statusLabel->setText("客户端已断开");
    }
}

void Connect::readData()
{
    QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
    if (!socket) return;

    while (socket->bytesAvailable() > 0) {
        QByteArray data = socket->readAll();
        QJsonDocument doc = QJsonDocument::fromJson(data);

        if (!doc.isNull() && doc.isObject()) {
            displayPointData(doc.object());
        } else {
            textEdit->append("无效数据: " + data);
        }
    }
}

QString Connect::convertDirection(double degrees)
{
    degrees = fmod(degrees, 360.0);
    if (degrees < 0) degrees += 360.0;

    if (degrees >= 0 && degrees < 90) {
        return QString("东偏北%1°").arg(QString::number(90 - degrees, 'f', 1));
    } else if (degrees >= 90 && degrees < 180) {
        return QString("西偏北%1°").arg(QString::number(degrees - 90, 'f', 1));
    } else if (degrees >= 180 && degrees < 270) {
        return QString("西偏南%1°").arg(QString::number(270 - degrees, 'f', 1));
    } else {
        return QString("东偏南%1°").arg(QString::number(degrees - 270, 'f', 1));
    }
}

Target Connect::parseTargetFromJson(const QJsonObject& obj, long id)
{
    Target t;
    t.id = id;

    // 字符串转 double
    t.relDistance = obj.contains("distance") ? obj["distance"].toString().toDouble() : 0.0;
    t.angle = obj["direction"].toString().toDouble();
    t.speed = obj["speed"].toString().toDouble();

    QString colorStr = obj["color"].toString();
    t.color = QColor(colorStr);

    // 坐标解析
    qreal x = obj["x"].toString().toDouble();
    qreal y = obj["y"].toString().toDouble();

    t.x = x;
    t.y = y;

    return t;
}


void Connect::displayPointData(const QJsonObject &pointData)
{
    double direction = pointData["direction"].toString().toDouble();
    QString directionStr = convertDirection(direction);

    QString info = QString("[%1] 收到数据:\n"
                           "坐标: (%2, %3)\n"
                           "方向: %4\n"
                           "速度: %5\n"
                           "颜色: %6\n"
                           "-------------------")
                       .arg(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"))
                       .arg(pointData["x"].toString())
                       .arg(pointData["y"].toString())
                       .arg(directionStr)
                       .arg(pointData["speed"].toString())
                       .arg(pointData["color"].toString());

    textEdit->append(info);

    Target target = parseTargetFromJson(pointData, pointId++);

    emit pointDataReceived(target);  // 发出信号
    pointId %= LONG_LONG_MAX; // 防止超限
}

